from .base import ViperBase
from .analysis import Analysis
from .tag import Tag
from .note import Note
from komand.exceptions import PluginException


class Malware(ViperBase):
    pathName = 'project/{project_name}/malware/'

    def __init__(self, config, project_name, **data):
        super().__init__(config)
        self.project_name = project_name
        self.id = data.get('id')
        self.name = data.get('name')
        self.crc32 = data.get('crc32')
        self.md5 = data.get('md5')
        self.sha1 = data.get('sha1')
        self.sha256 = data.get('sha256')
        self.sha512 = data.get('sha512')
        self.size = data.get('size')
        self.ssdeep = data.get('ssdeep')
        self.type = data.get('type')
        self.mime = data.get('mime')
        self.created_at = data.get('created_at')
        self.parent = data.get('parent')
        self.parent_id = data.get('parent_id')

        analyses_set = data.get('analysis_set')

        if analyses_set:
            analyses = []
            for result in analyses_set:
                if 'data' not in result:
                    break

                result_data = result['data']
                analyses.append(Analysis(self.config, self.project_name, self.sha256, **result_data).dump())

            self.analyses = analyses

        tag_set = data.get('tag_set')

        if tag_set:
            tags = []
            for result in tag_set:
                if 'data' not in result:
                    break

                result_data = result['data']
                tags.append(Tag(self.config, self.project_name, **result_data).dump())

            self.tags = tags

        note_set = data.get('note_set')

        if note_set:
            notes = []
            for result in note_set:
                if 'data' not in result:
                    break

                result_data = result['data']
                notes.append(Note(self.config, self.project_name, self.sha256, **result_data).dump())

            self.notes = notes

    def __str__(self):
        return self.sha256

    def download(self, compressor, password):
        url = self.pathName.format(project_name=self.project_name) + self.sha256 + "/download/"
        if not compressor or not password:
            response = super()._get(self.config, url, True)
        else:
            response = super()._post(self.config, url, None, True)
        return response

    def delete(self):
        url = self.pathName.format(project_name=self.project_name) + self.sha256 + "/"
        super()._delete(self.config, url)

    def create_note(self, title, body):
        data = {'title': title, 'body': body}
        url = self.pathName.format(project_name=self.project_name) + self.sha256 + "/note/"
        response = super()._post(self.config, url, data)

        if 'data' not in response:
            raise PluginException(cause='Error: Received an unexpected response.', assistance='Please verify your Viper server '
                            'status and try again. If the issue persists please contact support.')

        data = response['data']
        note = Note(self.config, self.project_name, self.sha256, **data)
        return note

    def get_note(self, id):
        url = self.pathName.format(project_name=self.project_name) + self.sha256 + "/note/" + str(id)
        response = super()._get(self.config, url)

        if 'data' not in response:
            raise PluginException(cause='Error: Received an unexpected response.', assistance='Please verify your Viper server '
                            'status and try again. If the issue persists please contact support.')

        data = response['data']
        return Note(self.config, self.project_name, self.sha256, **data)

    def get_analysis(self, id):
        url = self.pathName.format(project_name=self.project_name) + self.sha256 + "/analysis/" + str(id)
        response = super()._get(self.config, url)

        if 'data' not in response:
            raise PluginException(cause='Error: Received an unexpected response.', assistance='Please verify your Viper server '
                            'status and try again. If the issue persists please contact support.')

        data = response['data']
        return Analysis(self.config, self.project_name, self.sha256, **data)

    def create_tag(self, tag):
        data = {'tag': tag}
        url = self.pathName.format(project_name=self.project_name) + self.sha256 + "/tag/"
        response = super()._post(self.config, url, data)

        if 'data' not in response:
            raise PluginException(cause='Error: Received an unexpected response.', assistance='Please verify your Viper server '
                            'status and try again. If the issue persists please contact support.')

        data = response['data']
        result = Tag(self.config, self.project_name, **data)
        return result

    def dump(self):
        response = {
            "project_name": self.project_name,
            "id": self.id,
            "name": self.name,
            "crc32": self.crc32,
            "md5": self.md5,
            "sha1": self.sha1,
            "sha256": self.sha256,
            "sha512": self.sha512,
            "size": self.size,
            "ssdeep": self.ssdeep,
            "type": self.type,
            "mime": self.mime,
            "created_at": self.created_at
        }
        if self.parent:
            response["parent"] = self.parent
        if self.parent_id:
            response["parent_id"] = self.parent_id

        return response
